package com.hznu.coursemanagerbackend.modules.sys.controller;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.util.Value;
import com.hznu.coursemanagerbackend.common.utils.FileUtils;
import com.hznu.coursemanagerbackend.common.validator.Assert;
import com.hznu.coursemanagerbackend.config.UeditorUploadConfig;
import com.hznu.coursemanagerbackend.modules.sys.bean.*;
import com.hznu.coursemanagerbackend.modules.sys.entity.*;
import com.hznu.coursemanagerbackend.modules.sys.service.*;
import com.hznu.coursemanagerbackend.myBeans.R;
import com.xuxueli.poi.excel.ExcelExportUtil;
import com.xuxueli.poi.excel.ExcelImportUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author DragonDoor
 * @since 2018-11-12
 */
@EnableAutoConfiguration //自动载入应用程序所需的所有Bean
@RestController //@Controller与@ResponseBody的合并
@RequestMapping("/exerciseInfo")
@Api(description = "题目接口", value = "exerciseInfo")
public class ExerciseInfoController extends AbstractController {

    @Autowired
    ExerciseInfoService exerciseInfoService;

    @Autowired
    ExerkPointService exerkPointService;

    @Autowired
    ComposePaperService composePaperService;

    @Autowired
    KpointService kpointService;

    @Autowired
    AnswerRecordService answerRecordService;

    @Autowired
    ExerciseRecordService exerciseRecordService;

    @Autowired
    ExerciseCollectionService exerciseCollectionService;

    @Value("${template.exerciseTemplatepath}")
    private String exerciseTemplatepath = "题目导入模板.xls";

    /**
     * @Description:下载批量导入题目的模板
     * @param: request
     * @return:
     * @author: TateBrown
     * @Date: 2018/12/10
     */
    @ApiOperation("下载批量导入题目的模板")
    @GetMapping("/downloadtemplate")
    public ResponseEntity<byte[]> downloadTemplate(HttpServletRequest request) {
        try {
            byte[] data = FileUtils.ConvertFiletoByte(exerciseTemplatepath);
            HttpHeaders headers = new HttpHeaders();
            String filename = new String("题目导入模板.xls".getBytes("UTF-8"), "iso-8859-1");
            headers.setContentDispositionFormData("attachment", filename);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            HttpStatus statusCode = HttpStatus.OK;
            return new ResponseEntity<byte[]>(data, headers, statusCode);
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    /**
     * @Description:题目批量导入
     * @param: file
     * @return:
     * @author: TateBrown
     * @Date: 2018/12/10
     */
    @ApiOperation("题目批量导入")
    @PostMapping("/LoadExercise/{courseId}")
    public R LoadExercise(@PathVariable Integer courseId, @RequestParam("file") MultipartFile file) {
        try {
            //检查文件后缀
            String Suffix = FileUtils.getSuffix(file.getOriginalFilename());
            if (!Suffix.equals(".xls")) {
                return R.error("上传失败，请检查文件后缀，仅支持xls格式的Excel");
            }
            //从Excel文件中获取对象
            List<Object> exerciseLoadDtoList = ExcelImportUtil.importExcel(ExerciseLoadDto.class, file.getInputStream());
            Assert.isNull(exerciseLoadDtoList, "导入题目为空");
            //添加返回结果
            Integer count = exerciseInfoService.LoadBatch(exerciseLoadDtoList, courseId);

            return R.ok("添加完成,共添加成功" + count + "题");
        } catch (Exception e) {
            logger.error(e.toString());
            return R.error();
        }
    }

    /**
     * @Description:单个添加题目
     * @param: exerciseInfo
     * @return:
     * @author: Wqd
     * @Date: 2019/3/14
     */
    @ApiOperation("单个添加题目")
    @PostMapping("/add")
    public R add(@RequestBody ExerciseDetail exerciseDetail) {
        try {
                /*Assert.isNull(exerciseDetail.getKpoints(),"知识点未选择");
                Assert.isNull(exerciseDetail.getAnswer(),"答案不能为空");
                Assert.isNull(exerciseDetail.getType(),"题型未选择");
                Assert.isNull(exerciseDetail.getDlevel(),"难度未选择");
                Assert.isNull(exerciseDetail.getContent(),"题干不能为空");*/
            if (exerciseDetail.getExerciseInfoid() == -1) {
                ExerciseInfo exerciseInfo = new ExerciseInfo();
                exerciseInfo.setType(exerciseDetail.getType());
                exerciseInfo.setDlevel(exerciseDetail.getDlevel());
                exerciseInfo.setContent(exerciseDetail.getContent());
                exerciseInfo.setComment(exerciseDetail.getComment());
                exerciseInfo.setAnswer(exerciseDetail.getAnswer());
                exerciseInfo.setCourseid(exerciseDetail.getCourseid());
                exerciseInfo.setCreatorid(exerciseDetail.getCreatorid());
                exerciseInfo.setIsready(exerciseDetail.getIsready());
                exerciseInfoService.insert(exerciseInfo);
                if (exerciseDetail.getKpoints() != null) {
                    for (Integer id : exerciseDetail.getKpoints()) {
                        ExerkPoint exerkPoint = new ExerkPoint();
                        exerkPoint.setExerinfoid(exerciseInfo.getId());
                        exerkPoint.setKpointid(id);
                        exerkPointService.insert(exerkPoint);
                    }
                }
                return R.ok("题目保存成功").put("data", exerciseInfo.getId());
            } else {
                ExerciseInfo exerciseInfo1 = new ExerciseInfo();
                exerciseInfo1.setId(exerciseDetail.getExerciseInfoid());
                exerciseInfo1.setType(exerciseDetail.getType());
                exerciseInfo1.setDlevel(exerciseDetail.getDlevel());
                exerciseInfo1.setContent(exerciseDetail.getContent());
                exerciseInfo1.setComment(exerciseDetail.getComment());
                exerciseInfo1.setAnswer(exerciseDetail.getAnswer());
                exerciseInfo1.setCourseid(exerciseDetail.getCourseid());
                exerciseInfo1.setCreatorid(exerciseDetail.getCreatorid());
                exerciseInfo1.setIsready(exerciseDetail.getIsready());
                exerciseInfoService.updateById(exerciseInfo1);
                if (exerciseDetail.getKpoints() != null) {
                    for (Integer id : exerciseDetail.getKpoints()) {
                        ExerkPoint exerkPoint = new ExerkPoint();
                        exerkPoint.setExerinfoid(exerciseInfo1.getId());
                        exerkPoint.setKpointid(id);
                        exerkPointService.updateById(exerkPoint);
                    }
                }
                if (exerciseDetail.getIsready() == -1) {
                    return R.ok("题目保存成功");
                } else {
                    return R.ok("题目发布成功");
                }
            }
        } catch (Exception e) {
            logger.error(e.toString());
            return R.error();
        }
    }

    /**
     * @Description:统一请求接口
     * @param:
     * @return:
     * @author: TateBrown
     * @Date: 2018/12/11
     */
    @ApiOperation("统一请求接口")
    @GetMapping("/uploadPicture")
    public String ueGetInterface(String action) {
        try {
            if (action != null && action.equals("config")) {
                ObjectMapper mapper = new ObjectMapper();
                String config = mapper.writeValueAsString(new UeditorUploadConfig());
                return config;
            } else {
                return null;
            }
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    /**
     * @Description:富文本上传图片
     * @param:
     * @return:
     * @author: TateBrown
     * @Date: 2018/12/10
     */
    @ApiOperation("富文本上传图片")
    @PostMapping("/uploadPicture")
    public String uploadPicture(String action, MultipartFile file, HttpServletRequest request) {
        try {
            ImageState imageState = new ImageState();
            ObjectMapper mapper = new ObjectMapper();
            // 这里 就可已处理 图片存放的地址了
            if (action != null && action.equals("uploadimage")) {
                String dirPath = request.getSession().getServletContext().getRealPath("/images");
                new File(dirPath).mkdirs(); //创建目录
                //为防止重名使用时间戳重新命名
                String filename = "image" + Long.toString(System.currentTimeMillis()) + "." + FilenameUtils.getExtension(file.getOriginalFilename());
                String filePath = dirPath + "/" + filename;
                file.transferTo(new File(filePath));//转存文件
                imageState.setState("SUCCESS");
                imageState.setOriginal(file.getOriginalFilename());
                imageState.setSize(Long.toString(file.getSize()));
                imageState.setTitle(filename);
                imageState.setType(file.getContentType());
                String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/images/" + filename;
                imageState.setUrl(url);
                return mapper.writeValueAsString(imageState);
            } else {
                imageState.setState("无匹配的action类型");
                return mapper.writeValueAsString(imageState);
            }
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    /**
     * @Description: 修改题目详情，包括知识点
     * @param:
     * @return:
     * @author: TateBrown
     * @Date: 2018/12/11
     */
    @ApiOperation("修改题目详情")
    @PostMapping("/modify")
    public R modify(@RequestBody ExerciseDetail exerciseDetail) {
        try {
            ExerciseInfo exerciseInfo = new ExerciseInfo();
            exerciseInfo.setType(exerciseDetail.getType());
            exerciseInfo.setDlevel(exerciseDetail.getDlevel());
            exerciseInfo.setContent(exerciseDetail.getContent());
            exerciseInfo.setComment(exerciseDetail.getComment());
            exerciseInfo.setAnswer(exerciseDetail.getAnswer());
            exerciseInfo.setCourseid(exerciseDetail.getCourseid());
            exerciseInfo.setIsready(exerciseDetail.getIsready());
            exerciseInfo.setId(exerciseDetail.getId());
            exerciseInfoService.updateById(exerciseInfo);
            //删除原有知识点关联纪录
            exerkPointService.delete(new EntityWrapper<ExerkPoint>().eq("exerinfoid", exerciseDetail.getId()));
            if (exerciseDetail.getKpoints() != null) {
                for (Integer id : exerciseDetail.getKpoints()) {
                    ExerkPoint exerkPoint = new ExerkPoint();
                    exerkPoint.setExerinfoid(exerciseInfo.getId());
                    exerkPoint.setKpointid(id);
                    exerkPointService.insert(exerkPoint);
                }
            }
            return R.ok("修改成功");
        } catch (Exception e) {
            logger.error(e.toString());
            return R.error();
        }
    }

    /**
     * @Description:按题型，难度，知识点查找题目
     * @param:
     * @return:
     * @author: TateBrown
     * @Date: 2018/12/14
     */
    @ApiOperation("按题型难度知识点查找题目")
    @PostMapping("/findByCondition")
    public R findByCondition(@RequestBody ExerciseDetail exerciseDetail) {
        try {
            List<Integer> KpointIds = new LinkedList<Integer>();
            //找出所有知识点和所含有的子知识点
            if (exerciseDetail.getKpoints() != null) {
                //找到整个知识点树add进集合
                for (Integer id : exerciseDetail.getKpoints()) {
                    KpointIds.add(id);
                    List<Kpoint> childIds = kpointService.queryListByPid(id);
                    if (childIds != null)
                        for (Kpoint kpoint : childIds) {
                            KpointIds.add(kpoint.getId());
                        }
                }
                Integer[] kpoints = new Integer[KpointIds.size()];
                exerciseDetail.setKpoints(KpointIds.toArray(kpoints));
            }
            List<ExerciseDetail> exerciseDetailList = exerciseInfoService.findByCondition(exerciseDetail);
            List<ExerciseDetail> exerciseDetailList1 = new LinkedList<>();
            for (ExerciseDetail exerciseDetail1 : exerciseDetailList) {
                if (exerciseDetail1.getIsready() == 1) {
                    if(exerciseDetail1.getIsremove() == 1){
                        exerciseDetailList1.add(exerciseDetail1);
                    }
                }
            }
            return R.ok("查询成功").put("data", exerciseDetailList1);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return R.error();
        }
    }

    /**
     * @Description:根据练习id返回答案解析
     * @param:
     * @return:
     * @author: Wqd
     * @Date: 2019/3/6
     */
    @ApiOperation("根据练习id返回答案解析")
    @PostMapping("/getAnsweerAndComent/{exerciseInfoid}")
    public R Info(@PathVariable Integer exerciseInfoid) {
        ExerciseInfo exerciseInfo = exerciseInfoService.selectById(exerciseInfoid);
        return R.ok().put("data", exerciseInfo);
    }

    /**
     * @Description:根据条件筛获取该学生所有题目与所做的答案
     * @param:
     * @return:
     * @author: Wqd
     * @Date: 2019/3/6
     *
     */
    @ApiOperation("根据条件获取学生练习题目与答案")
    @PostMapping("/findByStudentCondition")
    public R findByStudentCondition(@RequestBody ExerciseDto exerciseDto) {
        try {
            List<Integer> KpointIds = new LinkedList<Integer>();
            //找出所有知识点和所含有的子知识点
            if (exerciseDto.getKpoints() != null) {
                //找到整个知识点树add进集合
                for (Integer id : exerciseDto.getKpoints()) {
                    KpointIds.add(id);
                    List<Kpoint> childIds = kpointService.queryListByPid(id);
                    if (childIds != null)
                        for (Kpoint kpoint : childIds) {
                            KpointIds.add(kpoint.getId());
                        }
                }
                Integer[] kpoints = new Integer[KpointIds.size()];
                exerciseDto.setKpoints(KpointIds.toArray(kpoints));
            }

            ExerciseDetail exerciseDetail = new ExerciseDetail();
            exerciseDetail.setKpoints(exerciseDto.getKpoints());
            exerciseDetail.setDlevel(exerciseDto.getDlevel());
            exerciseDetail.setType(exerciseDto.getType());
            exerciseDetail.setCourseid(exerciseDto.getCourseId());
            List<ExerciseDetail> exerciseDetails = exerciseInfoService.findByCondition(exerciseDetail);
            List<ExerciseDetail> exerciseDetailList = new LinkedList<>();
            for (ExerciseDetail exerciseDetail1 : exerciseDetails) {
                if(exerciseCollectionService.selectCount(new EntityWrapper<ExerciseCollection>().eq("exerciseinfoid",exerciseDetail1.getId()))!=0){
                    exerciseDetail1.setIsCollextion(1);
                }else{
                    exerciseDetail1.setIsCollextion(-1);
                }
                if (exerciseDetail1.getIsready() == 1) {
                    if(exerciseDetail1.getIsremove()==1){
                        if (exerciseDto.getFlag() == 0) {
                            if (answerRecordService.selectCount(new EntityWrapper<AnswerRecord>().eq("exerciseid", exerciseDetail1.getId()).eq("studentid", exerciseDto.getStudentId()).eq("examid", -1)) == 0) {
                                exerciseDetailList.add(exerciseDetail1);
                            }
                        } else if (exerciseDto.getFlag() == 1) {
                            AnswerRecord answerRecord = answerRecordService.selectOne(new EntityWrapper<AnswerRecord>().eq("exerciseid", exerciseDetail1.getId()).eq("studentid", exerciseDto.getStudentId()).eq("examid", -1));
                            if (answerRecord != null) {
                                exerciseDetail1.setStudentAnswer(exerciseRecordService.selectOne(new EntityWrapper<ExerciseRecord>().eq("answerrecordid", answerRecord.getId())).getAnswer());
                                exerciseDetailList.add(exerciseDetail1);
                            }
                        }
                    }
                }
            }
            Collections.reverse(exerciseDetailList);
            return R.ok().put("data", exerciseDetailList);
        } catch (Exception e) {
            logger.error(e.toString());
            return R.error(e.getMessage());
        }
    }

    /**
     * @Description:通过id删除未完成题目
     * @param: id
     * @return:
     * @author: Wqd
     * @Date: 2019/3/14
     */
    @ApiOperation("通过id删除未完成题目")
    @PostMapping("/remove/{id}")
    public R remove(@PathVariable Integer id) {
        try {
            List<ExerkPoint> exerkPointList= exerkPointService.selectList(new EntityWrapper<ExerkPoint>().eq("exerinfoid", id));
            for(ExerkPoint exerkPoint : exerkPointList){
                exerkPointService.deleteById(exerkPoint.getId());
            }
            exerciseInfoService.deleteById(id);
            return R.ok("删除成功");
        } catch (Exception e) {
            logger.error(e.toString());
            return R.error();
        }
    }

    /**
     * @Description:根据创建者id获取老师所有未编完的题目
     * @param:
     * @return:
     * @author: Wqd
     * @Date: 2019/3/6
     */
    @ApiOperation("根据创建者id获取老师所有未编完的题目")
    @PostMapping("/list/{creatorid}/{courseid}")
    public R list(@PathVariable Integer creatorid, @PathVariable Integer courseid) {
        List<ExerciseInfo> exerciseInfoList = exerciseInfoService.selectList(new EntityWrapper<ExerciseInfo>().eq("creatorid", creatorid).eq("courseid", courseid));
        List<ExerciseDetail> exerciseDetailList = new LinkedList<>();
        for (ExerciseInfo exerciseInfo : exerciseInfoList) {
            ExerciseDetail exerciseDetail = new ExerciseDetail();
            List<Integer> kpointList = new LinkedList<Integer>();
            List<ExerkPoint> exerkPointList = exerkPointService.selectList(new EntityWrapper<ExerkPoint>().eq("exerinfoid",exerciseInfo.getId()));
            for(ExerkPoint exerkPoint : exerkPointList){
                System.out.println("知识点是："+ exerkPoint.getKpointid());
                kpointList.add(exerkPoint.getKpointid());
            }
            Set<Integer> KpointIds = new TreeSet<>();
            for (Integer id : kpointList) {
                KpointIds.add(id);
                List<Kpoint> childIds = kpointService.queryListByPid(id);
                if (childIds != null) {
                    for (Kpoint kpoint : childIds) {
                        KpointIds.add(kpoint.getId());
                    }
                }
            }
            Integer[] kpoints = new Integer[KpointIds.size()];
            exerciseDetail.setKpoints(KpointIds.toArray(kpoints));

            exerciseDetail.setId(exerciseInfo.getId());
            exerciseDetail.setCreatorid(exerciseInfo.getCreatorid());
            exerciseDetail.setType(exerciseInfo.getType());
            exerciseDetail.setDlevel(exerciseInfo.getDlevel());
            exerciseDetail.setCourseid(exerciseInfo.getCourseid());
            exerciseDetail.setContent(exerciseInfo.getContent());
            exerciseDetail.setAnswer(exerciseInfo.getAnswer());
            exerciseDetail.setComment(exerciseInfo.getComment());
            exerciseDetail.setIsready(exerciseInfo.getIsready());
            exerciseDetail.setIsremove(exerciseInfo.getIsremove());
            if (exerciseDetail.getIsready() == -1) {
                exerciseDetailList.add(exerciseDetail);
            }
        }
        return R.ok().put("data", exerciseDetailList);
    }

    /**
     * @Description:根据id删除对应的题目
     * @param: id
     * @return:
     * @author: Wqd
     * @Date: 2019/4/1
     */
    @ApiOperation("根据id删除对应的题目")
    @PostMapping("/delete/{id}")
    public R delete(@PathVariable Integer id) {
        try {
            ExerciseInfo exerciseInfo = exerciseInfoService.selectById(id);
            if(composePaperService.selectCount(new EntityWrapper<ComposePaper>().eq("exerinfoid",id))!=0){
                exerciseInfo.setIsremove(-1);
                exerciseInfoService.updateById(exerciseInfo);
                return R.ok("删除成功");
            }else{
                exerciseInfoService.deleteById(id);
                return R.ok("删除成功");
            }
        } catch (Exception e) {
            logger.error(e.toString());
            return R.error();
        }
    }

}

